﻿using System;
using System.ComponentModel;
using System.Windows;
using nRoute.Components.Messaging;
#if (!WINRT)
using System.Windows.Controls;
using System.Windows.Interactivity;
using System.Windows.Markup;
#else
using nRoute.Behaviors.Interactivity;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Data;
using System.Windows.Interactivity;
using Windows.UI.Xaml.Markup;
#endif

namespace nRoute.Behaviors
{
#if (WINRT)
    [ContentProperty(Name = "Payload")]
#else
    [ContentProperty("Payload")]
#endif
    public class ChannelPublishAction
#if (WINRT)
        : TriggerAction<FrameworkElement>
#else
        : TriggerAction<DependencyObject>
#endif
    {
        public static readonly DependencyProperty PayloadProperty = 
            DependencyProperty.Register("Payload", typeof(Object), typeof(ChannelPublishAction),
            new PropertyMetadata(Utilities.Compatability.DP_UNSET_VALUE));

        public static readonly DependencyProperty ChannelTypeProperty = 
            DependencyProperty.Register("ChannelType", typeof(Type), typeof(ChannelPublishAction),
            new PropertyMetadata(Utilities.Compatability.DP_UNSET_VALUE));

        public static readonly DependencyProperty ChannelKeyProperty =
            DependencyProperty.Register("ChannelKey", typeof(string), typeof(ChannelPublishAction),
            new PropertyMetadata(Utilities.Compatability.DP_UNSET_VALUE));

        private bool _publishAsync;

#region Properties

        [Category("Common Properties")]
        public object Payload
        {
            get { return (Object)GetValue(PayloadProperty); }
            set { SetValue(PayloadProperty, value); }
        }

        [Category("Common Properties")]
        public Type ChannelType
        {
            get { return (Type)GetValue(ChannelTypeProperty); }
            set { SetValue(ChannelTypeProperty, value); }
        }

        [Category("Common Properties")]
        public string ChannelKey
        {
            get { return Convert.ToString(GetValue(ChannelKeyProperty)); }
            set { SetValue(ChannelKeyProperty, value); }
        }

        [Category("Common Properties")]
        public bool PublishAsync
        {
            get { return _publishAsync; }
            set { _publishAsync = value; }
        }

#if (WINRT)

        [Category("Common Properties")]
        [CustomPropertyValueEditor(CustomPropertyValueEditor.PropertyBinding)]
        public Binding PayloadBinding
        {
            get { return GetBinding(PayloadProperty); }
            set { SetBinding<Type>(PayloadProperty, value); }
        }

        [Category("Common Properties")]
        [CustomPropertyValueEditor(CustomPropertyValueEditor.PropertyBinding)]
        public Binding ChannelTypeBinding
        {
            get { return GetBinding(ChannelTypeProperty); }
            set { SetBinding<Type>(ChannelTypeProperty, value); }
        }

        [Category("Common Properties")]
        [CustomPropertyValueEditor(CustomPropertyValueEditor.PropertyBinding)]
        public Binding ChannelKeyBinding
        {
            get { return GetBinding(ChannelKeyProperty); }
            set { SetBinding<string>(ChannelKeyProperty, value); }
        }

#endif

#endregion

#region Trigger Related

        protected override void Invoke(object Type)
        {
            if (this.ChannelType != null)
            {
                if (!string.IsNullOrWhiteSpace(this.ChannelKey))
                {
                    Channel.Publish(this.ChannelType, this.ChannelKey, this.Payload, this.PublishAsync);
                }
                else
                {
                    Channel.Publish(this.ChannelType, this.Payload, this.PublishAsync);
                }
            }
            else if (Payload != null)
            {
                // guess the channel type by the payload type - wrong
                if (!string.IsNullOrWhiteSpace(this.ChannelKey))
                {
                    Channel.Publish(Payload.GetType(), this.ChannelKey, this.Payload, this.PublishAsync);
                }
                else
                {
                    Channel.Publish(Payload.GetType(), this.Payload, this.PublishAsync);
                }
            }

            // all else no error, as consistent with xaml controls
        }

#endregion

    }
}